package com.ezandroid.alphago.board;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.RectF;
import android.text.TextPaint;
import android.text.TextUtils;
import android.util.AttributeSet;

import com.ezandroid.alphago.R;
import com.ezandroid.alphago.util.AppConstants;
import com.ezandroid.alphago.util.AppPreference;
import com.ezandroid.alphago.util.TerrainAnalyze;

@SuppressLint("ViewConstructor")
public class GoBoard extends Grid {

    protected Bitmap mYunziBlackCubic;
    protected Bitmap mYunziWhiteCubic;

    protected Bitmap mHajiBlackCubic;
    protected Bitmap mHajiWhiteCubic;

    protected Bitmap mYunziBlackCubic2;
    protected Bitmap mYunziWhiteCubic2;

    protected Bitmap mHajiBlackCubic2;
    protected Bitmap mHajiWhiteCubic2;

    protected Bitmap mMuWen1Board;
    protected Bitmap mMuWen2Board;
    protected Bitmap mMuWen3Board;
    protected Bitmap mMuWen4Board;
    protected Bitmap mMuWen5Board;

    protected Bitmap mBlackShadow;
    protected Bitmap mWhiteShadow;

    protected int mBasicTextSize = 9;

    protected TextPaint mChessmanPaint;

    protected Paint mBoardPaint;

    protected int mMode;

    protected GoBoardOption mGoBoardOption = new GoBoardOption();

    private int mTouchX = -1, mTouchY = -1;

    public GoBoard(Context context, AttributeSet attrs, IBoardModel gm, int cubicSize,
                   int leftRightBorder, int topBottomBorder) {
        super(context, attrs, gm.getGridModel(), cubicSize, leftRightBorder, topBottomBorder);
        initView();
    }

    public GoBoard(Context context, IBoardModel gm, int cubicSize, int leftRightBorder,
                   int topBottomBorder) {
        super(context, gm.getGridModel(), cubicSize, leftRightBorder, topBottomBorder);
        initView();
    }

    public void setGoBoardOption(GoBoardOption goBoardOption) {
        if (goBoardOption != null) {
            mGoBoardOption = goBoardOption;
        }
    }

    public GoBoardOption getGoBoardOption() {
        return mGoBoardOption;
    }

    public void updateGoBoardOption() {
        mGoBoardOption.setBoardColor(AppPreference.getChessBoardColor(getContext()));
        mGoBoardOption.setBoardStyle(AppPreference.getChessBoardStyle(getContext()));
        mGoBoardOption.setIsShowCoordinate(AppPreference.getShowCoordinate(getContext()));
        mGoBoardOption.setLineWidth(AppPreference.getLineWidth(getContext()));
        mGoBoardOption.setPieceShadow(AppPreference.getChessPieceShadow(getContext()));
        mGoBoardOption.setPieceStyle(AppPreference.getChessPieceStyle(getContext()));
        mGoBoardOption.setShowNumber(AppPreference.getShowNumber(getContext()));
        mGoBoardOption.setNumberSize(AppPreference.getNumberSize(getContext()));
    }

    private void initView() {
        updateGoBoardOption();

        this.mYunziBlackCubic = BitmapFactory.decodeResource(this.getResources(), R.drawable.b2);
        this.mYunziWhiteCubic = BitmapFactory.decodeResource(this.getResources(), R.drawable.w2);

        this.mHajiBlackCubic = BitmapFactory.decodeResource(this.getResources(),
                R.drawable.stone_black);
        this.mHajiWhiteCubic = BitmapFactory.decodeResource(this.getResources(),
                R.drawable.stone_white);

        this.mYunziBlackCubic2 = BitmapFactory.decodeResource(this.getResources(), R.drawable.b4);
        this.mYunziWhiteCubic2 = BitmapFactory.decodeResource(this.getResources(), R.drawable.w4);

        this.mHajiBlackCubic2 = BitmapFactory.decodeResource(this.getResources(), R.drawable.b3);
        this.mHajiWhiteCubic2 = BitmapFactory.decodeResource(this.getResources(), R.drawable.w3);

        this.mBlackShadow = BitmapFactory.decodeResource(this.getResources(),
                R.drawable.blackshadow);
        this.mWhiteShadow = BitmapFactory.decodeResource(this.getResources(),
                R.drawable.whiteshadow);

        this.mBoardPaint = new Paint();
        this.mBoardPaint.setAntiAlias(true);

        this.mChessmanPaint = new TextPaint();
        this.mChessmanPaint.setAntiAlias(true);

        this.mBasicTextSize = mCubicSize / 2;
    }

    public void setMode(int mode) {
        this.mMode = mode;
    }

    public int getMode() {
        return this.mMode;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        setMeasuredDimension(mCubicSize * mGridModel.getGridSize() + 2 * mLeftRightBorder,
                mCubicSize * mGridModel.getGridSize() + 2 * mTopBottomBorder);
    }

    public void setTouchPosition(int touchX, int touchY) {
        mTouchX = touchX;
        mTouchY = touchY;
        postInvalidate();
    }

    @Override
    public void drawBoard(Canvas g) {
        int gridSize = mGridModel.getGridSize();
        // 1，绘制棋盘背景
        switch (mGoBoardOption.getBoardStyle()) {
            case AppConstants.CHESS_BOARD_STYLE_COLOR:
                mBoardPaint.setColor(mGoBoardOption.getBoardColor());
                g.drawRect(0, 0, mCubicSize * gridSize + 2 * mLeftRightBorder, mCubicSize * gridSize
                        + 2 * mTopBottomBorder, mBoardPaint);
                break;
            case AppConstants.CHESS_BOARD_STYLE_3D_1:
                if (mMuWen1Board == null || mMuWen1Board.isRecycled()) {
                    this.mMuWen1Board = BitmapFactory.decodeResource(this.getResources(),
                            R.drawable.board_1);
                }
                if (mMuWen2Board != null && !mMuWen2Board.isRecycled()) {
                    mMuWen2Board.recycle();
                    mMuWen2Board = null;
                }
                if (mMuWen3Board != null && !mMuWen3Board.isRecycled()) {
                    mMuWen3Board.recycle();
                    mMuWen3Board = null;
                }
                if (mMuWen4Board != null && !mMuWen4Board.isRecycled()) {
                    mMuWen4Board.recycle();
                    mMuWen4Board = null;
                }
                if (mMuWen5Board != null && !mMuWen5Board.isRecycled()) {
                    mMuWen5Board.recycle();
                    mMuWen5Board = null;
                }
                g.drawBitmap(mMuWen1Board,
                        new Rect(0, 0, mMuWen1Board.getWidth(), mMuWen1Board.getHeight()), new
                                Rect(0,
                                0, mCubicSize * gridSize + 2 * mLeftRightBorder, mCubicSize *
                                gridSize
                                + 2 * mTopBottomBorder), mBoardPaint);
                break;
            case AppConstants.CHESS_BOARD_STYLE_3D_2:
                if (mMuWen2Board == null || mMuWen2Board.isRecycled()) {
                    this.mMuWen2Board = BitmapFactory.decodeResource(this.getResources(),
                            R.drawable.board_2);
                }
                if (mMuWen1Board != null && !mMuWen1Board.isRecycled()) {
                    mMuWen1Board.recycle();
                    mMuWen1Board = null;
                }
                if (mMuWen3Board != null && !mMuWen3Board.isRecycled()) {
                    mMuWen3Board.recycle();
                    mMuWen3Board = null;
                }
                if (mMuWen4Board != null && !mMuWen4Board.isRecycled()) {
                    mMuWen4Board.recycle();
                    mMuWen4Board = null;
                }
                if (mMuWen5Board != null && !mMuWen5Board.isRecycled()) {
                    mMuWen5Board.recycle();
                    mMuWen5Board = null;
                }
                g.drawBitmap(mMuWen2Board,
                        new Rect(0, 0, mMuWen2Board.getWidth(), mMuWen2Board.getHeight()), new
                                Rect(0,
                                0, mCubicSize * gridSize + 2 * mLeftRightBorder, mCubicSize *
                                gridSize
                                + 2 * mTopBottomBorder), mBoardPaint);
                break;
            case AppConstants.CHESS_BOARD_STYLE_3D_3:
                if (mMuWen3Board == null || mMuWen3Board.isRecycled()) {
                    this.mMuWen3Board = BitmapFactory.decodeResource(this.getResources(),
                            R.drawable.board_3);
                }
                if (mMuWen1Board != null && !mMuWen1Board.isRecycled()) {
                    mMuWen1Board.recycle();
                    mMuWen1Board = null;
                }
                if (mMuWen2Board != null && !mMuWen2Board.isRecycled()) {
                    mMuWen2Board.recycle();
                    mMuWen2Board = null;
                }
                if (mMuWen4Board != null && !mMuWen4Board.isRecycled()) {
                    mMuWen4Board.recycle();
                    mMuWen4Board = null;
                }
                if (mMuWen5Board != null && !mMuWen5Board.isRecycled()) {
                    mMuWen5Board.recycle();
                    mMuWen5Board = null;
                }
                g.drawBitmap(mMuWen3Board,
                        new Rect(0, 0, mMuWen3Board.getWidth(), mMuWen3Board.getHeight()), new
                                Rect(0,
                                0, mCubicSize * gridSize + 2 * mLeftRightBorder, mCubicSize *
                                gridSize
                                + 2 * mTopBottomBorder), mBoardPaint);
                break;
            case AppConstants.CHESS_BOARD_STYLE_3D_4:
                if (mMuWen4Board == null || mMuWen4Board.isRecycled()) {
                    this.mMuWen4Board = BitmapFactory.decodeResource(this.getResources(),
                            R.drawable.kaya);
                }
                if (mMuWen1Board != null && !mMuWen1Board.isRecycled()) {
                    mMuWen1Board.recycle();
                    mMuWen1Board = null;
                }
                if (mMuWen2Board != null && !mMuWen2Board.isRecycled()) {
                    mMuWen2Board.recycle();
                    mMuWen2Board = null;
                }
                if (mMuWen3Board != null && !mMuWen3Board.isRecycled()) {
                    mMuWen3Board.recycle();
                    mMuWen3Board = null;
                }
                if (mMuWen5Board != null && !mMuWen5Board.isRecycled()) {
                    mMuWen5Board.recycle();
                    mMuWen5Board = null;
                }
                g.drawBitmap(mMuWen4Board,
                        new Rect(0, 0, mMuWen4Board.getWidth(), mMuWen4Board.getHeight()), new
                                Rect(0,
                                0, mCubicSize * gridSize + 2 * mLeftRightBorder, mCubicSize *
                                gridSize
                                + 2 * mTopBottomBorder), mBoardPaint);
                break;
            case AppConstants.CHESS_BOARD_STYLE_3D_5:
                if (mMuWen5Board == null || mMuWen5Board.isRecycled()) {
                    this.mMuWen5Board = BitmapFactory.decodeResource(this.getResources(),
                            R.drawable.oak);
                }
                if (mMuWen1Board != null && !mMuWen1Board.isRecycled()) {
                    mMuWen1Board.recycle();
                    mMuWen1Board = null;
                }
                if (mMuWen2Board != null && !mMuWen2Board.isRecycled()) {
                    mMuWen2Board.recycle();
                    mMuWen2Board = null;
                }
                if (mMuWen3Board != null && !mMuWen3Board.isRecycled()) {
                    mMuWen3Board.recycle();
                    mMuWen3Board = null;
                }
                if (mMuWen4Board != null && !mMuWen4Board.isRecycled()) {
                    mMuWen4Board.recycle();
                    mMuWen4Board = null;
                }
                g.drawBitmap(mMuWen5Board,
                        new Rect(0, 0, mMuWen5Board.getWidth(), mMuWen5Board.getHeight()), new
                                Rect(0,
                                0, mCubicSize * gridSize + 2 * mLeftRightBorder, mCubicSize *
                                gridSize
                                + 2 * mTopBottomBorder), mBoardPaint);
                break;
        }

        if (mGoBoardOption.isShowCoordinate()) {
            // 2，绘制棋盘坐标
            mBoardPaint.setColor(Color.BLACK);
            mBoardPaint.setTextSize(mBasicTextSize);
            // 纵坐标
            for (int i = 0; i < gridSize; i++) {
                String s = "" + (i + 1);
                float sw = mBoardPaint.measureText(s);
                g.drawText(s, mCubicSize - sw - mBasicTextSize / 2, (gridSize - i) * mCubicSize
                        + mBasicTextSize / 2, mBoardPaint);
            }
            // 横坐标
            char c = 'A';
            for (int i = 0; i < gridSize; i++) {
                char cc = (char) (c + i);
                String s;
                float sw;
                if (cc >= 'I') {
                    s = "" + (char) (cc + 1);
                } else {
                    s = "" + cc;
                }
                sw = mBoardPaint.measureText(s);
                g.drawText(s, (i + 1) * mCubicSize - sw / 2, mCubicSize - mBasicTextSize / 2,
                        mBoardPaint);
            }
        }

        // 3，绘制棋盘线
        mBoardPaint.setColor(Color.BLACK);
        g.translate(mLeftRightBorder + mCubicSize / 2, mTopBottomBorder + mCubicSize / 2);
        for (int i = 0; i < gridSize; i++) {
            switch (mGoBoardOption.getLineWidth()) {
                case AppConstants.LINE_WIDTH_BIG:
                    if (i == 0 || i == gridSize - 1) {
                        mBoardPaint.setStrokeWidth(2.5f);
                    } else {
                        mBoardPaint.setStrokeWidth(1.5f);
                    }
                    break;
                case AppConstants.LINE_WIDTH_MIDDLE:
                    if (i == 0 || i == gridSize - 1) {
                        mBoardPaint.setStrokeWidth(2.0f);
                    } else {
                        mBoardPaint.setStrokeWidth(1.25f);
                    }
                    break;
                case AppConstants.LINE_WIDTH_SMALL:
                    if (i == 0 || i == gridSize - 1) {
                        mBoardPaint.setStrokeWidth(1.5f);
                    } else {
                        mBoardPaint.setStrokeWidth(1.0f);
                    }
                    break;
            }
            g.drawLine(0, i * mCubicSize, mCubicSize * (gridSize - 1), i * mCubicSize, mBoardPaint);
            g.drawLine(i * mCubicSize, 0, i * mCubicSize, mCubicSize * (gridSize - 1), mBoardPaint);
        }
        g.translate(-(mLeftRightBorder + mCubicSize / 2), -(mTopBottomBorder + mCubicSize / 2));

        // 4，绘制星位
        for (int i = 0; i < gridSize; i++) {
            for (int j = 0; j < gridSize; j++) {
                switch (gridSize) {
                    case 9:
                        if ((i == 2 || i == 6) && (j == 2 || j == 6) || (i == 4 && j == 4)) {
                            drawStar(g, i, j);
                        }
                        break;
                    case 13:
                        if ((i == 3 || i == 9) && (j == 3 || j == 9) || (i == 6 && j == 6)) {
                            drawStar(g, i, j);
                        }
                        break;
                    case 19:
                        if ((i == 3 || i == 9 || i == 15) && (j == 3 || j == 9 || j == 15)) {
                            drawStar(g, i, j);
                        }
                        break;
                }
            }
        }

        // 绘制按下状态
        drawTouch(g, mTouchX, mTouchY);
    }

    @Override
    public void drawChessman(Canvas g, int col, int row) {
        // 绘制棋子
        drawPiece(g, col, row);
        // 绘制数字
        drawNumber(g, col, row);
        // 绘制标记
        drawMark(g, col, row);
        // 绘制字母
        drawLetter(g, col, row);
        // 绘制标签
        drawLabel(g, col, row);
        // 绘制当前形势
        drawTerrain(g, col, row);
        // 绘制当前高亮状态
        drawStyle(g, col, row);
    }

    /**
     * 绘制按下状态
     *
     * @param g
     * @param i
     * @param j
     */
    private void drawTouch(Canvas g, int i, int j) {
        if (i != -1 && j != -1) {
            int gridSize = mGridModel.getGridSize();
            mBoardPaint.setColor(Color.BLUE);
            g.translate(mLeftRightBorder + mCubicSize / 2, mTopBottomBorder + mCubicSize / 2);
            mBoardPaint.setStrokeWidth(3.0f);
            g.drawLine(0, j * mCubicSize, mCubicSize * (gridSize - 1), j * mCubicSize, mBoardPaint);
            g.drawLine(i * mCubicSize, 0, i * mCubicSize, mCubicSize * (gridSize - 1), mBoardPaint);
            g.translate(-(mLeftRightBorder + mCubicSize / 2), -(mTopBottomBorder + mCubicSize / 2));
        }
    }

    /**
     * 绘制数字
     *
     * @param g
     * @param i
     * @param j
     */
    private void drawNumber(Canvas g, int i, int j) {
        GoPoint p = (GoPoint) mGridModel.getObject(i, j);
        int cb = mCubicSize;
        int number = p.getNumber();
        switch (mGoBoardOption.getNumberSize()) {
            case AppConstants.NUMBER_SIZE_BIG:
                if (number / 100 > 0) {
                    mChessmanPaint.setTextSize(mBasicTextSize + 2);
                } else if (number / 10 > 0) {
                    mChessmanPaint.setTextSize(mBasicTextSize + 4);
                } else {
                    mChessmanPaint.setTextSize(mBasicTextSize + 6);
                }
                break;
            case AppConstants.NUMBER_SIZE_SMALL:
                if (number / 100 > 0) {
                    mChessmanPaint.setTextSize(mBasicTextSize - 2);
                } else if (number / 10 > 0) {
                    mChessmanPaint.setTextSize(mBasicTextSize);
                } else {
                    mChessmanPaint.setTextSize(mBasicTextSize + 2);
                }
                break;
            case AppConstants.NUMBER_SIZE_MIDDLE:
            default:
                if (number / 100 > 0) {
                    mChessmanPaint.setTextSize(mBasicTextSize);
                } else if (number / 10 > 0) {
                    mChessmanPaint.setTextSize(mBasicTextSize + 2);
                } else {
                    mChessmanPaint.setTextSize(mBasicTextSize + 4);
                }
                break;
        }
        if (p.getPlayer() == GoPoint.PLAYER_BLACK
                || (p.getPlayer() == GoPoint.PLAYER_WHITE && mMode == AppConstants
                .MODE_SINGLE_COLOR)) {
            int showNumber = mGoBoardOption.getShowNumber();
            // 绘制手数
            if (number > 0
                    && (showNumber == AppConstants.SHOW_NUMBER_ALL || (showNumber == AppConstants
                    .SHOW_NUMBER_ONLY_LAST && p
                    .getStyle() == GoPoint.STYLE_HIGHLIGHT))) {
                mChessmanPaint.setColor(Color.WHITE);
                float width = mChessmanPaint.measureText("" + number);
                float height = mChessmanPaint.getTextSize();
                g.drawText("" + number, cb / 2 - width / 2, cb / 2 + height / 3, mChessmanPaint);
            }
        } else if (p.getPlayer() == GoPoint.PLAYER_WHITE) {
            int showNumber = mGoBoardOption.getShowNumber();
            // 绘制手数
            if (number > 0
                    && (showNumber == AppConstants.SHOW_NUMBER_ALL || (showNumber == AppConstants
                    .SHOW_NUMBER_ONLY_LAST && p
                    .getStyle() == GoPoint.STYLE_HIGHLIGHT))) {
                mChessmanPaint.setColor(Color.BLACK);
                float width = mChessmanPaint.measureText("" + number);
                float height = mChessmanPaint.getTextSize();
                g.drawText("" + number, cb / 2 - width / 2, cb / 2 + height / 3, mChessmanPaint);
            }
        }
    }

    /**
     * 绘制星位
     *
     * @param g
     * @param i
     * @param j
     */
    private void drawStar(Canvas g, int i, int j) {
        g.translate(mLeftRightBorder + i * mCubicSize, mTopBottomBorder + j * mCubicSize);
        mBoardPaint.setColor(Color.BLACK);
        mBoardPaint.setStyle(Style.FILL);
        g.drawArc(new RectF(mCubicSize / 2 - 4, mCubicSize / 2 - 4, mCubicSize / 2 + 4,
                mCubicSize / 2 + 4), 0, 360, true, mBoardPaint);
        g.translate(-(mLeftRightBorder + i * mCubicSize), -(mTopBottomBorder + j * mCubicSize));
    }

    private void drawWhiteShadow1And2(Canvas g) {
        int cb = mCubicSize;
        // 绘制阴影
        switch (mGoBoardOption.getPieceShadow()) {
            case AppConstants.CHESS_PIECE_SHADOW_BIG:
                g.drawBitmap(mWhiteShadow,
                        new Rect(0, 0, mWhiteShadow.getWidth(), mWhiteShadow.getHeight()),
                        new RectF(cb / 36 - cb / 7, cb / 36, 35 * cb / 36 + cb / 7, 35 * cb / 36
                                + cb
                                / 3.5f), mChessmanPaint);
                break;
            case AppConstants.CHESS_PIECE_SHADOW_MIDDLE:
                g.drawBitmap(mWhiteShadow,
                        new Rect(0, 0, mWhiteShadow.getWidth(), mWhiteShadow.getHeight()), new
                                RectF(cb
                                / 36 - cb / 8, cb / 36, 35 * cb / 36 + cb / 8, 35 * cb / 36 + cb
                                / 4),
                        mChessmanPaint);
                break;
            case AppConstants.CHESS_PIECE_SHADOW_SMALL:
                g.drawBitmap(mWhiteShadow,
                        new Rect(0, 0, mWhiteShadow.getWidth(), mWhiteShadow.getHeight()),
                        new RectF(cb / 36 - cb / 9, cb / 36, 35 * cb / 36 + cb / 9, 35 * cb / 36
                                + cb
                                / 4.5f), mChessmanPaint);
                break;
        }
    }

    private void drawWhiteShadow3And4(Canvas g) {
        int cb = mCubicSize;
        // 绘制阴影
        switch (mGoBoardOption.getPieceShadow()) {
            case AppConstants.CHESS_PIECE_SHADOW_BIG:
                g.drawBitmap(mWhiteShadow,
                        new Rect(0, 0, mWhiteShadow.getWidth(), mWhiteShadow.getHeight()),
                        new RectF(cb / 36 - cb / 5, cb / 36, 35 * cb / 36 + cb / 5, 35 * cb / 36
                                + cb
                                / 2.5f), mChessmanPaint);
                break;
            case AppConstants.CHESS_PIECE_SHADOW_MIDDLE:
                g.drawBitmap(mWhiteShadow,
                        new Rect(0, 0, mWhiteShadow.getWidth(), mWhiteShadow.getHeight()), new
                                RectF(cb
                                / 36 - cb / 6, cb / 36, 35 * cb / 36 + cb / 6, 35 * cb / 36 + cb
                                / 3),
                        mChessmanPaint);
                break;
            case AppConstants.CHESS_PIECE_SHADOW_SMALL:
                g.drawBitmap(mWhiteShadow,
                        new Rect(0, 0, mWhiteShadow.getWidth(), mWhiteShadow.getHeight()),
                        new RectF(cb / 36 - cb / 7, cb / 36, 35 * cb / 36 + cb / 7, 35 * cb / 36
                                + cb
                                / 3.5f), mChessmanPaint);
                break;
        }
    }

    private void drawBlackShadow1And2(Canvas g) {
        int cb = mCubicSize;
        // 绘制阴影
        switch (mGoBoardOption.getPieceShadow()) {
            case AppConstants.CHESS_PIECE_SHADOW_BIG:
                g.drawBitmap(mBlackShadow,
                        new Rect(0, 0, mBlackShadow.getWidth(), mBlackShadow.getHeight()),
                        new RectF(cb / 36 - cb / 7, cb / 36, 35 * cb / 36 + cb / 7, 35 * cb / 36
                                + cb
                                / 3.5f), mChessmanPaint);
                break;
            case AppConstants.CHESS_PIECE_SHADOW_MIDDLE:
                g.drawBitmap(mBlackShadow,
                        new Rect(0, 0, mBlackShadow.getWidth(), mBlackShadow.getHeight()), new
                                RectF(cb
                                / 36 - cb / 8, cb / 36, 35 * cb / 36 + cb / 8, 35 * cb / 36 + cb
                                / 4),
                        mChessmanPaint);
                break;
            case AppConstants.CHESS_PIECE_SHADOW_SMALL:
                g.drawBitmap(mBlackShadow,
                        new Rect(0, 0, mBlackShadow.getWidth(), mBlackShadow.getHeight()),
                        new RectF(cb / 36 - cb / 9, cb / 36, 35 * cb / 36 + cb / 9, 35 * cb / 36
                                + cb
                                / 4.5f), mChessmanPaint);
                break;
        }
    }

    private void drawBlackShadow3And4(Canvas g) {
        int cb = mCubicSize;
        // 绘制阴影
        switch (mGoBoardOption.getPieceShadow()) {
            case AppConstants.CHESS_PIECE_SHADOW_BIG:
                g.drawBitmap(mBlackShadow,
                        new Rect(0, 0, mBlackShadow.getWidth(), mBlackShadow.getHeight()),
                        new RectF(cb / 36 - cb / 5, cb / 36, 35 * cb / 36 + cb / 5, 35 * cb / 36
                                + cb
                                / 2.5f), mChessmanPaint);
                break;
            case AppConstants.CHESS_PIECE_SHADOW_MIDDLE:
                g.drawBitmap(mBlackShadow,
                        new Rect(0, 0, mBlackShadow.getWidth(), mBlackShadow.getHeight()), new
                                RectF(cb
                                / 36 - cb / 6, cb / 36, 35 * cb / 36 + cb / 6, 35 * cb / 36 + cb
                                / 3),
                        mChessmanPaint);
                break;
            case AppConstants.CHESS_PIECE_SHADOW_SMALL:
                g.drawBitmap(mBlackShadow,
                        new Rect(0, 0, mBlackShadow.getWidth(), mBlackShadow.getHeight()),
                        new RectF(cb / 36 - cb / 7, cb / 36, 35 * cb / 36 + cb / 7, 35 * cb / 36
                                + cb
                                / 3.5f), mChessmanPaint);
                break;
        }
    }

    /**
     * 绘制棋子
     *
     * @param g
     * @param col
     * @param row
     */
    private void drawPiece(Canvas g, int col, int row) {
        GoPoint p = (GoPoint) mGridModel.getObject(col, row);
        int cb = mCubicSize;
        if (p.getPlayer() == GoPoint.PLAYER_BLACK
                || (p.getPlayer() == GoPoint.PLAYER_WHITE && mMode == AppConstants
                .MODE_SINGLE_COLOR)) {
            int pieceStyle = mGoBoardOption.getPieceStyle();
            if (pieceStyle == AppConstants.CHESS_PIECE_STYLE_2D) {
                mChessmanPaint.setColor(Color.BLACK);
                mChessmanPaint.setStyle(Style.FILL);
                g.drawArc(new RectF(cb / 36, cb / 36, cb * 35 / 36, cb * 35 / 36), 0, 360, true,
                        mChessmanPaint);
            } else {
                // 绘制棋子
                switch (pieceStyle) {
                    case AppConstants.CHESS_PIECE_STYLE_3D_1: {
                        drawBlackShadow1And2(g);
                        g.drawBitmap(mYunziBlackCubic, new Rect(0, 0, mYunziBlackCubic.getWidth(),
                                mYunziBlackCubic.getHeight()), new RectF(cb / 36, cb / 36,
                                35 * cb / 36, 35 * cb / 36), mChessmanPaint);
                    }
                    break;
                    case AppConstants.CHESS_PIECE_STYLE_3D_2: {
                        drawBlackShadow1And2(g);
                        g.drawBitmap(mHajiBlackCubic, new Rect(0, 0, mHajiBlackCubic.getWidth(),
                                mHajiBlackCubic.getHeight()), new RectF(cb / 36, cb / 36, 35 * cb
                                / 36,
                                35 * cb / 36), mChessmanPaint);
                    }
                    break;
                    case AppConstants.CHESS_PIECE_STYLE_3D_3: {
                        drawBlackShadow3And4(g);
                        g.drawBitmap(mYunziBlackCubic2, new Rect(0, 0, mYunziBlackCubic2.getWidth(),
                                mYunziBlackCubic2.getHeight()), new RectF(cb / 36, cb / 36,
                                35 * cb / 36, 35 * cb / 36), mChessmanPaint);
                    }
                    break;
                    case AppConstants.CHESS_PIECE_STYLE_3D_4: {
                        drawBlackShadow3And4(g);
                        g.drawBitmap(mHajiBlackCubic2, new Rect(0, 0, mHajiBlackCubic2.getWidth(),
                                mHajiBlackCubic2.getHeight()), new RectF(cb / 36, cb / 36,
                                35 * cb / 36, 35 * cb / 36), mChessmanPaint);
                    }
                    break;
                }
            }
        } else if (p.getPlayer() == GoPoint.PLAYER_WHITE) {
            int pieceStyle = mGoBoardOption.getPieceStyle();
            if (pieceStyle == AppConstants.CHESS_PIECE_STYLE_2D) {
                mChessmanPaint.setColor(Color.WHITE);
                mChessmanPaint.setStyle(Style.FILL);
                g.drawArc(new RectF(cb / 36, cb / 36, cb * 35 / 36, cb * 35 / 36), 0, 360, true,
                        mChessmanPaint);
                mChessmanPaint.setColor(Color.BLACK);
                mChessmanPaint.setStyle(Style.STROKE);
                g.drawArc(new RectF(cb / 36, cb / 36, cb * 35 / 36, cb * 35 / 36), 0, 360, true,
                        mChessmanPaint);
            } else {
                // 绘制棋子
                switch (pieceStyle) {
                    case AppConstants.CHESS_PIECE_STYLE_3D_1: {
                        drawWhiteShadow1And2(g);
                        g.drawBitmap(mYunziWhiteCubic, new Rect(0, 0, mYunziWhiteCubic.getWidth(),
                                mYunziWhiteCubic.getHeight()), new RectF(cb / 36, cb / 36,
                                35 * cb / 36, 35 * cb / 36), mChessmanPaint);
                    }
                    break;
                    case AppConstants.CHESS_PIECE_STYLE_3D_2: {
                        drawWhiteShadow1And2(g);
                        g.drawBitmap(mHajiWhiteCubic, new Rect(0, 0, mHajiWhiteCubic.getWidth(),
                                mHajiWhiteCubic.getHeight()), new RectF(cb / 36, cb / 36, 35 * cb
                                / 36,
                                35 * cb / 36), mChessmanPaint);
                    }
                    break;
                    case AppConstants.CHESS_PIECE_STYLE_3D_3: {
                        drawWhiteShadow3And4(g);
                        g.drawBitmap(mYunziWhiteCubic2, new Rect(0, 0, mYunziWhiteCubic2.getWidth(),
                                mYunziWhiteCubic2.getHeight()), new RectF(cb / 36, cb / 36,
                                35 * cb / 36, 35 * cb / 36), mChessmanPaint);
                    }
                    break;
                    case AppConstants.CHESS_PIECE_STYLE_3D_4: {
                        drawWhiteShadow3And4(g);
                        g.drawBitmap(mHajiWhiteCubic2, new Rect(0, 0, mHajiWhiteCubic2.getWidth(),
                                mHajiWhiteCubic2.getHeight()), new RectF(cb / 36, cb / 36,
                                35 * cb / 36, 35 * cb / 36), mChessmanPaint);
                    }
                    break;
                }
            }
        }
    }

    /**
     * 绘制当前高亮状态
     *
     * @param g
     * @param col
     * @param row
     */
    private void drawStyle(Canvas g, int col, int row) {
        GoPoint p = (GoPoint) mGridModel.getObject(col, row);
        int cb = mCubicSize;
        if (p.getStyle() == GoPoint.STYLE_HIGHLIGHT) {
            int showNumber = mGoBoardOption.getShowNumber();
            if (showNumber == AppConstants.SHOW_NUMBER_OFF) {
                float oldStrokeWidth = mChessmanPaint.getStrokeWidth();
                float newStrokeWidth = 2f;
                if (p.getPlayer() == GoPoint.PLAYER_BLACK
                        || (p.getPlayer() == GoPoint.PLAYER_WHITE && mMode == AppConstants
                        .MODE_SINGLE_COLOR)) {
                    mChessmanPaint.setColor(Color.WHITE);
                } else if (p.getPlayer() == GoPoint.PLAYER_WHITE) {
                    mChessmanPaint.setColor(Color.BLACK);
                }
                mChessmanPaint.setStyle(Style.STROKE);
                mChessmanPaint.setStrokeWidth(newStrokeWidth);
                g.drawArc(new RectF(cb / 5f, cb / 5f, cb * 4f / 5, cb * 4f / 5), 0, 360, true,
                        mChessmanPaint);
                mChessmanPaint.setStrokeWidth(oldStrokeWidth);
            } else if (showNumber == AppConstants.SHOW_NUMBER_ONLY_LAST) {
            } else {
                mChessmanPaint.setColor(Color.RED);
                mChessmanPaint.setStyle(Style.FILL);
                g.drawArc(new RectF(cb / 3, cb / 3, cb * 2 / 3, cb * 2 / 3), 0, 360, true,
                        mChessmanPaint);
            }
        } else if (p.getStyle() == GoPoint.STYLE_READY) {
            mChessmanPaint.setColor(Color.GREEN);
            mChessmanPaint.setStyle(Style.FILL);
            g.drawArc(new RectF(cb / 5f, cb / 5f, cb * 4f / 5, cb * 4f / 5), 0, 360, true,
                    mChessmanPaint);
        }
    }

    private Path mTempPath;

    private Path getTempPath() {
        if (mTempPath == null) {
            // 绘制这个三角形,你可以绘制任意多边形
            mTempPath = new Path();
            // 此点为多边形的起点
            mTempPath.moveTo(mCubicSize / 2, mCubicSize / 5);
            mTempPath.lineTo(mCubicSize * 3 / 4, mCubicSize * 3 / 5);
            mTempPath.lineTo(mCubicSize / 4, mCubicSize * 3 / 5);
            // 使这些点构成封闭的多边形
            mTempPath.close();
        }
        return mTempPath;
    }

    /**
     * 绘制标记
     *
     * @param g
     * @param col
     * @param row
     */
    private void drawMark(Canvas g, int col, int row) {
        GoPoint p = (GoPoint) mGridModel.getObject(col, row);
        int cb = mCubicSize;
        int mark = p.getMark();
        if (mark != GoPoint.NONE) {
            mChessmanPaint.setColor(Color.RED);
            mChessmanPaint.setStyle(Style.FILL);
            if (mark == GoPoint.TRIANGLE) {
                g.drawPath(getTempPath(), mChessmanPaint);
            } else if (mark == GoPoint.SQUARE) {
                g.drawRect(cb / 4, cb / 4, cb * 3 / 4, cb * 3 / 4, mChessmanPaint);
            } else if (mark == GoPoint.CIRCLE) {
                g.drawArc(new RectF(cb / 4, cb / 4, cb * 3 / 4, cb * 3 / 4), 0, 360, true,
                        mChessmanPaint);
            } else if (mark == GoPoint.CROSS) {
                g.drawLine(cb / 4, cb / 4, cb * 3 / 4, cb * 3 / 4, mChessmanPaint);
                g.drawLine(cb / 4, cb * 3 / 4, cb * 3 / 4, cb / 4, mChessmanPaint);
            }
        }
    }

    /**
     * 绘制字母
     *
     * @param g
     * @param col
     * @param row
     */
    private void drawLetter(Canvas g, int col, int row) {
        GoPoint p = (GoPoint) mGridModel.getObject(col, row);
        int cb = mCubicSize;
        int letter = p.getLetter();
        if (letter != GoPoint.NONE) {
            mChessmanPaint.setColor(Color.MAGENTA);
            mChessmanPaint.setTextSize(mBasicTextSize + 4);
            char cp = (char) letter;
            float width = mChessmanPaint.measureText("" + cp);
            float height = mChessmanPaint.getTextSize();
            g.drawText("" + cp, cb / 2 - width / 2, cb / 2 + height / 3, mChessmanPaint);
        }
    }

    /**
     * 绘制标签
     *
     * @param g
     * @param col
     * @param row
     */
    private void drawLabel(Canvas g, int col, int row) {
        GoPoint p = (GoPoint) mGridModel.getObject(col, row);
        int cb = mCubicSize;
        String label = p.getLabel();
        if (!TextUtils.isEmpty(label)) {
            mChessmanPaint.setColor(Color.MAGENTA);
            mChessmanPaint.setTextSize(mBasicTextSize + 4);
            float width = mChessmanPaint.measureText(label);
            float height = mChessmanPaint.getTextSize();
            g.drawText(label, cb / 2 - width / 2, cb / 2 + height / 3, mChessmanPaint);
        }
    }

    /**
     * 绘制当前形势
     */
    private void drawTerrain(Canvas g, int col, int row) {
        GoPoint p = (GoPoint) mGridModel.getObject(col, row);
        int cb = mCubicSize;
        float terrain = p.getTerrain();
        if (terrain >= TerrainAnalyze.THRESHOLD) {
            mChessmanPaint.setColor(Color.BLACK);
            mChessmanPaint.setStyle(Style.FILL);
            g.drawArc(new RectF(cb / 3, cb / 3, cb * 2 / 3, cb * 2 / 3), 0, 360, true,
                    mChessmanPaint);
        } else if (terrain <= -TerrainAnalyze.THRESHOLD) {
            mChessmanPaint.setColor(Color.WHITE);
            mChessmanPaint.setStyle(Style.FILL);
            g.drawArc(new RectF(cb / 3, cb / 3, cb * 2 / 3, cb * 2 / 3), 0, 360, true,
                    mChessmanPaint);
        }
    }
}
